JFreeChart Versions - Diving into Differences and Similarities

This notebook reports code and results of the analysis conducted on the two versions of the JfreeChart software system included in the dataset (i.e. $0.6.0$ and $0.7.1$).

The goal of the analysis is to provide insights on the differences and/or similarities between the methods included in both systems, along with some considerations on the coherence of methods included only in one of the two.

Utilities

Utilities functions used throughout this notebook. Feel free to skip to the **Analisys Section** directly.

Preamble


In [1]:
# %load preamble_directives.py
"""Some imports and path settings to make notebook code
running smoothly.
"""
# Author: Valerio Maggio <valeriomaggio@gmail.com>
# Copyright (c) 2015 Valerio Maggio <valeriomaggio@gmail.com>
# License: BSD 3 clause

import sys, os
# Extending PYTHONPATH to allow relative import!
sys.path.append(os.path.join(os.path.abspath(os.path.curdir), '..'))

# Import Django Settings
from django.conf import settings
# Import Comments_Classification (Django) Project Settings
from comments_classification import settings as comments_classification_settings

try:
    settings.configure(**comments_classification_settings.__dict__)
except RuntimeError:
    # settings already configured
    pass

# ---------------------
# Module Import Section
# ---------------------
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Text Processing Functions (for code and comments)


In [2]:
import re

def strip_tags(text):
    """Strips all HTML tags from text"""
    HTML_TAG_RE = re.compile(r'<[^>]+>')
    return HTML_TAG_RE.sub('', text)

In [3]:
from string import punctuation

def strip_punctuations(text, allowed='@'):
    """Strips all the punctuation character from the input comment.
    
    Parameters
    ----------
    text : str
        The input text to process

    allowed : str, optional. 
        The list of punctuation characters to exclude from the processing
        (default is '@' as for JavaDoc Comments).
    
    """
    black_list = punctuation
    for c in allowed:
        black_list = black_list.replace(c, '')
    for p in black_list:
        text = text.replace(p, ' ')
    return '\n'.join(' '.join(w for w in line.split() if len(w)) for line in text.splitlines() if len(line))

In [4]:
def normalise_lines(text):
    """Removes additional (trailing) spaces from lines of the given text and 
    returns it normalised (no extra spaces)"""
    return '\n'.join(l.strip() for l in text.splitlines() if len(l.strip()))

In [5]:
def extract_locs(code_fragment):
    """Normalise and returns the lines of code in the input fragment."""
    locs = ' '.join(l.strip() for st in code_fragment.split(';') for l in st.splitlines() 
                    if len(l.strip()) and len(strip_punctuations(l.strip())))
    return locs

Pipeline Process

Helper class that aids the creation and the application of multiple text processing functions


In [6]:
class Pipeline(object):
    """Implements a simple linear pipeline process"""
    
    def __init__(self, *callables):
        """Creates a new Pipeline of processes (i.e. `callables`.)
        Each of this callable, must always return a value as it 
        will represent the new `data` parameter passed through 
        the pipeline till finally returned.
        
        Parameters
        ----------
        callables : list
            A list of callables (e.g. functions) of arity one.
            This list constitutes the set of filters of the pipeline.
        """
        self._filters = list(callables)
        
    @property
    def filters(self):
        return self._filters

    def __iadd__(self, process):
        if not callable(process):
            raise ValueError('The value should be a callable')
        
        from inspect import signature
        sig_process = signature(process)
        if len(sig_process.parameters) != 1:
            raise ValueError('The input function must have arity one!')
            
        self._filters.append(process)
        return self
    
    def process(self, data):
        """Execute the pipeline"""
        for callable in self._filters:
            data = callable(data)
        return data

Function to Analyse Coherence


In [7]:
NOT_EVALUATED = -1
DONT_KNOW = 2
FURTHER_EVAL = 5
AGREEMENT = 3
STRONG_AGREEMENT = 4 

def is_coherent(method):
    """Return wheter or not comment is coherent with its method implementation according to judges evaluations.
    
    Parameters
    ----------
    method : `source_code_analysis.models.CodeMethod`
        Instance of a `CodeMethod` model holding the reference to its corresponding evaluations.
        
    Returns
    -------
    bool : 
        True if the evaluation (the first one retrieved from the db) corresponds to an
        AGREEMENT | STRONG_AGREEMENT value.
    """
    return (method.agreement_evaluations.last().agreement_vote in (AGREEMENT, STRONG_AGREEMENT))

def has_agreement_evaluations(method):
    """Check that input methods has agreement evaluations interesting for the current analysis
    (i.e. different from DONT_KNOW).
    
    Parameters
    ----------
    method : `source_code_analysis.models.CodeMethod`
        Instance of a `CodeMethod` model holding the reference to its corresponding evaluations.
        
    Returns
    -------
    bool : 
        True if the evaluation (the first one retrieved from the db) does **not** 
        correspond to a DONT_KNOW value.
    """
    return (method.agreement_evaluations.last().agreement_vote not in (NOT_EVALUATED, 
                                                                       DONT_KNOW, FURTHER_EVAL))

Functions to gather Data from the DB


In [8]:
def signature(code_fragment):
    """Returns the signature of a method extracted from the input code fragment.
    
    Parameters
    ----------
    code_fragment : str
        The implementation code of a method (i.e. method.code_fragment attribute)
        
    Returns
    -------
    str :
        The signature string of the method
    
    """
    first_line = code_fragment[:code_fragment.find('{')]
    return ' '.join([l.strip() for l in first_line.splitlines() if len(l.strip())])

In [9]:
def gather_all_methods(sw_project):
    """Gather all methods for the input software project
    
    Parameters
    ----------
    sw_project : `source_code_analysis.models.SoftwareProject`
        Target Software Project
        
    Returns
    -------
    dict : 
        A dictionary mapping all methods with its unique key.
        This key is extremely important to correctly identify similarities among 
        multiple versions of the same software. 
    
        In more details, the key for a single *method* is defined by the following triple:

        * Name of the Source File
        * Name of the Class
        * Signature of the method
    """
    
    # gather all methods
    methods = filter(has_agreement_evaluations, sw_project.code_methods.all())
    
    # create the map
    methods_map = dict()
    for method in methods:
        key = '{}{}{}'.format(method.code_class.src_filename, 
                              method.code_class.class_name, 
                              signature(method.code_fragment))
        if not key in methods_map:
            methods_map[key] = method
        else:
            print('Key already present: ')
            print('Current method ID: ', method.id)
            print('Already present method: ', methods_map[key].id)
    
    # return map
    return methods_map

Utility function to test processing results and check what's going on


In [10]:
def randomly_pick_a_method_from(list_of_methods_keys, with_code=False, with_coherence=False):
    """Randomly pick a method from the input collection of keys and print the 
    corresponding lead comments. If `with_code` parameter is provided, 
    the code_fragment is printed as well.
    Moreover, if the `with_coherence` parameter is True, the corresponding coherence evaluation is 
    reported in the output, as well.
    """
    
    from random import choice
    random_key = choice(list_of_methods_keys)

    method_in_jf060 = jf060_methods[random_key]
    method_in_jf071 = jf071_methods[random_key]

    print('='*80)
    print('Method in JFreeChart 0.6.0', end=' ')
    if with_coherence:
        print('Is Coherent: ', is_coherent(method_in_jf060))
    else:
        print('')
    
    print(method_in_jf060.comment)
    if with_code:
        print('')
        print(method_in_jf060.code_fragment)
    
    print('\n\n')
    
    print('Method in JFreeChart 0.7.1', end=' ')
    if with_coherence:
        print('Is Coherent: ', is_coherent(method_in_jf071))
    else:
        print('')
        
    print(method_in_jf071.comment)
    if with_code:
        print('')
        print(method_in_jf071.code_fragment)
    
    print('='*80, end='\n\n')

Analysis

Load Data


In [11]:
from source_code_analysis.models import SoftwareProject

In [12]:
jfreechart_060 = SoftwareProject.objects.get(name__iexact='JFreeChart', version='0.6.0')
jfreechart_071 = SoftwareProject.objects.get(name__iexact='JFreeChart', version='0.7.1')

In [13]:
jf060_methods = gather_all_methods(jfreechart_060)
jf071_methods = gather_all_methods(jfreechart_071)

Total Stats (starting point)


In [14]:
print('Total No. of Methods in JFreeChart 0.6.0: ', len(jf060_methods))
print('Total No. of Methods in JFreeChart 0.7.1: ', len(jf071_methods))


Total No. of Methods in JFreeChart 0.6.0:  461
Total No. of Methods in JFreeChart 0.7.1:  588

Back to top

Common Methods


In [15]:
# Set of all the Keys in common between the two considered versions
methods_in_common = set(jf060_methods.keys()).intersection(set(jf071_methods.keys()))
print('Total Methods in Common: ', len(methods_in_common))


Total Methods in Common:  283

Back to top

Analysis of the Comments


In [16]:
# Set the Pipelines
comment_pipeline = Pipeline(strip_tags, strip_punctuations, normalise_lines)

# List to store the references to methods 
# sharing (or not) the same comment between the two versions
same_comment = list()
different_comment = list()
    
for mkey in methods_in_common:
    comment_in_060 = comment_pipeline.process(jf060_methods[mkey].comment)
    comment_in_071 = comment_pipeline.process(jf071_methods[mkey].comment)
    
    if comment_in_060 == comment_in_071:
        same_comment.append(mkey)
    else:
        different_comment.append(mkey)

Back to top

Stats


In [17]:
print('Total Number of Methods in Common: ', len(methods_in_common))
print('\t No. of those Sharing the Same Comment: ', len(same_comment))
print('\t No. of those With Differences in Comment: ', len(different_comment))


Total Number of Methods in Common:  283
	 No. of those Sharing the Same Comment:  257
	 No. of those With Differences in Comment:  26

Back to top

Methods in Common with the Same Comment


In [18]:
# Test: get a random key and check that they actually share the same comments 
# regardless the formattings (e.g. trailing spaces)
randomly_pick_a_method_from(same_comment)  # Test 1
randomly_pick_a_method_from(same_comment)  # Test 2
randomly_pick_a_method_from(same_comment)  # Test 3
randomly_pick_a_method_from(same_comment)  # Test 4


================================================================================
Method in JFreeChart 0.6.0 
/**
   * Returns the width of each bar in the chart.
   * @param area The area within which the plot will be drawn.
   */



Method in JFreeChart 0.7.1 
/**

   * Returns the width of each bar in the chart.

   * @param area The area within which the plot will be drawn.

   */
================================================================================

================================================================================
Method in JFreeChart 0.6.0 
/**
   * Sets a reference to the plot that the axis is assigned to.
   * <P>
   * This method is called by Plot in the setHorizontalAxis() and setVerticalAxis() methods.
   * You shouldn't need to call the method yourself.
   * @param plot The plot that the axis belongs to.
   */



Method in JFreeChart 0.7.1 
/**

   * Sets a reference to the plot that the axis is assigned to.

   * <P>

   * This method is called by Plot in the setHorizontalAxis() and setVerticalAxis() methods.

   * You shouldn't need to call the method yourself.

   * @param plot The plot that the axis belongs to.

   */
================================================================================

================================================================================
Method in JFreeChart 0.6.0 
/**
   * Sets the label for the axis.
   * <P>
   * Registered listeners are notified of a general change to the axis.
   * @param label The new label for the axis (null permitted).
   */



Method in JFreeChart 0.7.1 
/**

   * Sets the label for the axis.

   * <P>

   * Registered listeners are notified of a general change to the axis.

   * @param label The new label for the axis (null permitted).

   */
================================================================================

================================================================================
Method in JFreeChart 0.6.0 
/**
   * Returns the color/shade used for the tick labels.
   * @return The color/shade used for the tick labels.
   */



Method in JFreeChart 0.7.1 
/**

   * Returns the color/shade used for the tick labels.

   * @return The color/shade used for the tick labels.

   */
================================================================================

Back to top

Take Away No. 1

From the total set of $283$ methods in common between JFreeChart 0.6.0 and 0.7.1,

  • $257$ ($\approx 91\%$) have no significant differences in comments (differences limited only to text formattings and punctuaction characters)
    • Hence this changes do not affect the coherence evaluation in any way.

Back to top

Methods in Common with Different Comments


In [19]:
# Qualitative Analysis (preliminary)

randomly_pick_a_method_from(different_comment)  # Test 1
randomly_pick_a_method_from(different_comment)  # Test 2
randomly_pick_a_method_from(different_comment)  # Test 3
randomly_pick_a_method_from(different_comment)  # Test 4


================================================================================
Method in JFreeChart 0.6.0 
/**
   * Standard constructor: builds a DateAxis with mostly default attributes.
   */



Method in JFreeChart 0.7.1 
/**

   * Constructs a date axis, using default values where necessary.

   * @param label The axis label.

   */
================================================================================

================================================================================
Method in JFreeChart 0.6.0 
/**
   * Sets the gap between the last bar in one category and the first bar in the
   * next category, and notifies registered listeners that the plot has been modified.
   * @param gap The new gap value.
   */



Method in JFreeChart 0.7.1 
/**

   * Sets the gap between the last bar in one category and the first bar in the

   * next category, and notifies registered listeners that the plot has been modified.

   * @param percent The new gap value, expressed as a percentage of the width of the plot area

   *        (0.05 = 5 percent).

   */
================================================================================

================================================================================
Method in JFreeChart 0.6.0 
/**
   * Full constructor - builds a new DateTitle with the specified attributes.
   * @param location the relative location of this title (use constants in AbstractTitle);
   * @param alignment the text alignment of this title (use constants in AbstractTitle);
   * @param dateStyle the Date style to use (SHORT, MEDIUM, LONG, or FULL constants from
   *          java.text.DateFormat);
   * @param locale the locale to use to format this date (if you are unsure what to use here, use
   *         Locale.getDefault() for your default locale);
   * @param font the font used to display the date;
   * @param paint the paint used to display the date;
   * @param insets the blank space around the outside of the title;
   */



Method in JFreeChart 0.7.1 
/**

   * Constructs a new DateTitle with the specified attributes.

   * @param location the relative location of this title (use constants in AbstractTitle).

   * @param alignment the text alignment of this title (use constants in AbstractTitle).

   * @param dateStyle the Date style to use (SHORT, MEDIUM, LONG, or FULL constants from

   *          java.text.DateFormat).

   * @param locale the locale to use to format this date (if you are unsure what to use here, use

   *         Locale.getDefault() for your default locale).

   * @param font the font used to display the date.

   * @param paint the paint used to display the date.

   * @param insets the blank space around the outside of the title.

   */
================================================================================

================================================================================
Method in JFreeChart 0.6.0 
/**
   * Calculates and returns the value of the lowest visible tick on the axis.
   */



Method in JFreeChart 0.7.1 
/**

   * Calculates the value of the lowest visible tick on the axis.

   * @return The value of the lowest visible tick on the axis.

   */
================================================================================

Back to top

Take Away No. 2:

At a first glance, considering the comments of the methods included in the list of $26$ those with different comments, differences appear quite resonable (thus not only limited to layout and formattings).


Back to top

Analysis of the Implementation

Back to top

Analysis of the Implementation for Methods with the Same Comment


In [20]:
methods_with_same_comments = same_comment  # code readability purposes

# Set the Pipeline
code_pipeline = Pipeline(extract_locs)

same_comment_and_code = list()
same_comment_different_code = list()

for mkey in methods_with_same_comments:
    code_in_060 = code_pipeline.process(jf060_methods[mkey].code_fragment)
    code_in_071 = code_pipeline.process(jf071_methods[mkey].code_fragment)
        
    if code_in_060 == code_in_071:
        same_comment_and_code.append(mkey)
    else:
        same_comment_different_code.append(mkey)

In [21]:
print('Total Number of Common Methods with the same comments: ', len(methods_with_same_comments))
print('\t No. of those Sharing the Same Code: ', len(same_comment_and_code))
print('\t No. of those With Differences in Code: ', len(same_comment_different_code))


Total Number of Common Methods with the same comments:  257
	 No. of those Sharing the Same Code:  225
	 No. of those With Differences in Code:  32

Back to top

Take Away No. 3:

Among the $257$ methods in common between the two version that shares the same comment:

  • $225$ methods ($\approx 88\%$) have no difference in the implementation
  • $32$ methods have changes in code (and thus not in comments)

Back to top

Analysis of the Implementation for Methods with Different Comments


In [22]:
methods_with_different_comments = different_comment  # code readability purposes

# Set the Pipeline
code_pipeline = Pipeline(extract_locs)

different_comment_same_code = list()
different_comment_and_code = list()

for mkey in methods_with_different_comments:
    code_in_060 = code_pipeline.process(jf060_methods[mkey].code_fragment)
    code_in_071 = code_pipeline.process(jf071_methods[mkey].code_fragment)
        
    if code_in_060 == code_in_071:
        different_comment_same_code.append(mkey)
    else:
        different_comment_and_code.append(mkey)

In [23]:
print('Total Number of Common Methods with different comments: ', len(methods_with_different_comments))
print('\t No. of those Sharing the Same Code: ', len(different_comment_same_code))
print('\t No. of those With Differences in Code: ', len(different_comment_and_code))


Total Number of Common Methods with different comments:  26
	 No. of those Sharing the Same Code:  16
	 No. of those With Differences in Code:  10

Back to top

Take Away No. 4:

Among the $26$ methods in common between the two version that have differences in their lead comments:

  • $16$ methods ($\approx 62\%$) have no difference in the implementation
  • $10$ methods have changes in code (as well as in comments)

Back to top

Analysis of the Coherence

Back to top

Coherence of Methods with Same Comments and Code


In [24]:
same_coherence = list()
coherence_changed = list()

for mkey in same_comment_and_code:
    mth_in_060 = jf060_methods[mkey]
    mth_in_071 = jf071_methods[mkey]
    
    if is_coherent(mth_in_060) == is_coherent(mth_in_071):
        same_coherence.append(mkey)
    else:
        coherence_changed.append(mkey)

In [25]:
print('Total Number of Methods Sharing the same Lead Comment and Code')
print('\t Same Coherence: ', len(same_coherence))
print('\t Different Coherence', len(coherence_changed))


Total Number of Methods Sharing the same Lead Comment and Code
	 Same Coherence:  225
	 Different Coherence 0

Result

No differences occur in the evaluation of coherences for common methods sharing the same code and comments (as expected)

Back to top

Coherence of Methods with Same Comments but Different Code


In [26]:
same_coherence = list()
coherence_changed = list()

for mkey in same_comment_different_code:
    mth_in_060 = jf060_methods[mkey]
    mth_in_071 = jf071_methods[mkey]
    
    if is_coherent(mth_in_060) == is_coherent(mth_in_071):
        same_coherence.append(mkey)
    else:
        coherence_changed.append(mkey)

In [27]:
print('Total Number of Methods sharing the same lead comment but have different code', len(same_comment_different_code))
print('\t Same Coherence: ', len(same_coherence))
print('\t Different Coherence', len(coherence_changed))


Total Number of Methods sharing the same lead comment but have different code 32
	 Same Coherence:  32
	 Different Coherence 0

In [28]:
# Try to spot some insights
randomly_pick_a_method_from(same_comment_different_code, with_code=True, with_coherence=True)  # Method 1
randomly_pick_a_method_from(same_comment_different_code, with_code=True, with_coherence=True)  # Method 2
randomly_pick_a_method_from(same_comment_different_code, with_code=True, with_coherence=True)  # Method 3
randomly_pick_a_method_from(same_comment_different_code, with_code=True, with_coherence=True)  # Method 4


================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Creates a scatter plot with default settings.
   * @param title The chart title.
   * @param xAxisLabel A label for the X-axis.
   * @param yAxisLabel A label for the Y-axis.
   * @param data The dataset for the chart.
   * @param legend A flag specifying whether or not a legend is required.
   */

  public static JFreeChart createScatterPlot(String title, String xAxisLabel, String yAxisLabel,
                         XYDataset data, boolean legend) {

    JFreeChart chart = null;

  try {
      Axis xAxis = new HorizontalNumberAxis(xAxisLabel);
    Axis yAxis = new VerticalNumberAxis(yAxisLabel);
      XYPlot plot = new XYPlot(xAxis, yAxis);
      plot.setXYItemRenderer(new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES));
    chart = new JFreeChart(data, plot, title, JFreeChart.DEFAULT_TITLE_FONT, legend);
  }
  catch (AxisNotCompatibleException e) {
      // this won't happen unless you mess with the axis constructors above
    System.err.println("ChartFactory.createScatterPlot(...) : axis not compatible.");
  }
  catch (PlotNotCompatibleException e) {
      // this won't happen unless you mess with the axis constructors above
    System.err.println("ChartFactory.createScatterPlot(...) : plot not compatible.");
  }

    return chart;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Creates a scatter plot with default settings.

   * @param title The chart title.

   * @param xAxisLabel A label for the X-axis.

   * @param yAxisLabel A label for the Y-axis.

   * @param data The dataset for the chart.

   * @param legend A flag specifying whether or not a legend is required.

   */

  public static JFreeChart createScatterPlot(String title, String xAxisLabel, String yAxisLabel,

                         XYDataset data, boolean legend) {

    ValueAxis xAxis = new HorizontalNumberAxis(xAxisLabel);

    ValueAxis yAxis = new VerticalNumberAxis(yAxisLabel);

    XYPlot plot = new XYPlot(xAxis, yAxis);

    plot.setXYItemRenderer(new StandardXYItemRenderer(StandardXYItemRenderer.SHAPES));

    JFreeChart chart = new JFreeChart(data, plot, title, JFreeChart.DEFAULT_TITLE_FONT, legend);

    return chart;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Selects an appropriate tick value for the axis.  The strategy is to display as many ticks as
   * possible (selected from an array of 'standard' tick units) without the labels overlapping.
   * @param g2 The graphics device;
   * @param drawArea The area in which the plot and axes should be drawn;
   * @param plotArea The area in which the plot should be drawn;
   */

  private void selectAutoTickUnit(Graphics2D g2, Rectangle2D drawArea, Rectangle2D plotArea) {
    // calculate the tick label height...
    FontRenderContext frc = g2.getFontRenderContext();
    double tickLabelHeight = tickLabelFont.getLineMetrics("123", frc).getHeight()
                 +this.tickLabelInsets.top+this.tickLabelInsets.bottom;
    // now find the smallest tick unit that will accommodate the labels...
  double zero = this.translatedValue(Plot.ZERO, plotArea);
    // start with the current tick unit...
    NumberTickUnit candidate1
             = (NumberTickUnit)this.standardTickUnits.getNearestTickUnit(this.tickUnit);
    double y = this.translatedValue(candidate1.getValue(), plotArea);
    double unitHeight = Math.abs(y-zero);
    // then extrapolate...
    double bestguess = (tickLabelHeight/unitHeight) * candidate1.value.doubleValue();
    NumberTickUnit guess = new NumberTickUnit(new Double(bestguess), null);
    NumberTickUnit candidate2
               = (NumberTickUnit)this.standardTickUnits.getNearestTickUnit(guess);
    this.tickUnit = candidate2;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Selects an appropriate tick value for the axis.  The strategy is to display as many ticks as

   * possible (selected from an array of 'standard' tick units) without the labels overlapping.

   * @param g2 The graphics device;

   * @param drawArea The area in which the plot and axes should be drawn;

   * @param plotArea The area in which the plot should be drawn;

   */

  private void selectAutoTickUnit(Graphics2D g2, Rectangle2D drawArea, Rectangle2D plotArea) {

    // calculate the tick label height...

    FontRenderContext frc = g2.getFontRenderContext();

    double tickLabelHeight = tickLabelFont.getLineMetrics("123", frc).getHeight()

                 +this.tickLabelInsets.top+this.tickLabelInsets.bottom;

    // now find the smallest tick unit that will accommodate the labels...

  double zero = this.translateValueToJava2D(0.0, plotArea);

    // start with the current tick unit...

    NumberTickUnit candidate1

             = (NumberTickUnit)this.standardTickUnits.getNearestTickUnit(this.tickUnit);

    double y = this.translateValueToJava2D(candidate1.getValue().doubleValue(), plotArea);

    double unitHeight = Math.abs(y-zero);

    // then extrapolate...

    double bestguess = (tickLabelHeight/unitHeight) * candidate1.value.doubleValue();

    NumberTickUnit guess = new NumberTickUnit(new Double(bestguess), null);

    NumberTickUnit candidate2

               = (NumberTickUnit)this.standardTickUnits.getNearestTickUnit(guess);

    this.tickUnit = candidate2;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Creates and returns a default instance of a VerticalXYBarChart based on the specified
   * dataset.
   * @param title The chart title.
   * @param xAxisLabel A label for the X-axis.
   * @param yAxisLabel A label for the Y-axis.
   * @param data The dataset for the chart.
   * @param legend A flag specifying whether or not a legend is required.
   */

  public static JFreeChart createVerticalXYBarChart(String title, String xAxisLabel,
                            String yAxisLabel, IntervalXYDataset data,
                            boolean legend) {

    JFreeChart chart = null;

  try {
    HorizontalDateAxis timeAxis = new HorizontalDateAxis(xAxisLabel);
    Axis valueAxis = new VerticalNumberAxis(yAxisLabel);
    Plot plot = new VerticalXYBarPlot(timeAxis, valueAxis, new Insets(0,0,0,0), Color.white,
      new BasicStroke(), Color.gray);
    chart = new JFreeChart(data, plot, title, JFreeChart.DEFAULT_TITLE_FONT, legend);
  }
  catch (AxisNotCompatibleException e) {
      // this won't happen unless you mess with the axis constructors above
    System.err.println("ChartFactory.createVerticalXYBarChart(...) : axis not compatible.");
  }
  catch (PlotNotCompatibleException e) {
      // this won't happen unless you mess with the axis constructors above
    System.err.println("ChartFactory.createVerticalXYBarChart(...) : plot not compatible.");
  }

    return chart;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Creates and returns a default instance of a VerticalXYBarChart based on the specified

   * dataset.

   * @param title The chart title.

   * @param xAxisLabel A label for the X-axis.

   * @param yAxisLabel A label for the Y-axis.

   * @param data The dataset for the chart.

   * @param legend A flag specifying whether or not a legend is required.

   */

  public static JFreeChart createVerticalXYBarChart(String title, String xAxisLabel,

                            String yAxisLabel, IntervalXYDataset data,

                            boolean legend) {

    HorizontalDateAxis timeAxis = new HorizontalDateAxis(xAxisLabel);

    ValueAxis valueAxis = new VerticalNumberAxis(yAxisLabel);

    //Plot plot = new VerticalXYBarPlot(timeAxis, valueAxis, new Insets(0,0,0,0), Color.white,

    //                  new BasicStroke(), Color.gray);

    XYPlot plot = new XYPlot(timeAxis, valueAxis, new Insets(0,0,0,0), Color.white,

                 new BasicStroke(), Color.gray);

    plot.setXYItemRenderer(new VerticalXYBarRenderer());

    JFreeChart chart = new JFreeChart(data, plot, title, JFreeChart.DEFAULT_TITLE_FONT, legend);

    return chart;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Draws the plot on a Java 2D graphics device (such as the screen or a printer).
   * @param g2 The graphics device;
   * @param drawArea The area within which the chart should be drawn.
   * @param plotArea The area within which the plot should be drawn (a subset of the drawArea).
   */

  public void draw(Graphics2D g2, Rectangle2D drawArea, Rectangle2D plotArea) {
  // draw the axis label
  if (this.label!=null) {
    g2.setFont(labelFont);
    g2.setPaint(labelPaint);
    Rectangle2D labelBounds = labelFont.getStringBounds(label, g2.getFontRenderContext());
    if (labelDrawnVertical) {
    double xx = drawArea.getX()+labelInsets.left+labelBounds.getHeight();
    double yy = plotArea.getY()+plotArea.getHeight()/2+(labelBounds.getWidth()/2);
    drawVerticalString(label, g2, (float)xx, (float)yy);
    }
    else {
    double xx = drawArea.getX()+labelInsets.left;
    double yy = drawArea.getY()+drawArea.getHeight()/2-labelBounds.getHeight()/2;
    g2.drawString(label, (float)xx, (float)yy);
    }
  }
  // draw the tick labels and marks and gridlines
  this.refreshTicks(g2, drawArea, plotArea);
  double xx = plotArea.getX();
  g2.setFont(tickLabelFont);
  Iterator iterator = ticks.iterator();
  while (iterator.hasNext()) {
    Tick tick = (Tick)iterator.next();
    float yy = (float)this.translatedValue(tick.getNumericalValue(), plotArea);
    if (tickLabelsVisible) {
    g2.setPaint(this.tickLabelPaint);
    g2.drawString(tick.getText(), tick.getX(), tick.getY());
    }
    if (tickMarksVisible) {
    g2.setStroke(this.getTickMarkStroke());
    Line2D mark = new Line2D.Double(plotArea.getX()-2, yy,
            plotArea.getX()+2, yy);
    g2.draw(mark);
    }
    if (showGridLines) {
    g2.setStroke(gridStroke);
    g2.setPaint(gridPaint);
    Line2D gridline = new Line2D.Double(xx, yy,
              plotArea.getMaxX(), yy);
    g2.draw(gridline);




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Draws the plot on a Java 2D graphics device (such as the screen or a printer).

   * @param g2 The graphics device;

   * @param drawArea The area within which the chart should be drawn.

   * @param plotArea The area within which the plot should be drawn (a subset of the drawArea).

   */



  public void draw(Graphics2D g2, Rectangle2D drawArea, Rectangle2D plotArea) {

  // draw the axis label

  if (this.label!=null) {

    g2.setFont(labelFont);

    g2.setPaint(labelPaint);

    Rectangle2D labelBounds = labelFont.getStringBounds(label, g2.getFontRenderContext());

    if (labelDrawnVertical) {

    double xx = drawArea.getX()+labelInsets.left+labelBounds.getHeight();

    double yy = plotArea.getY()+plotArea.getHeight()/2+(labelBounds.getWidth()/2);

    drawVerticalString(label, g2, (float)xx, (float)yy);

    }

    else {

    double xx = drawArea.getX()+labelInsets.left;

    double yy = drawArea.getY()+drawArea.getHeight()/2-labelBounds.getHeight()/2;

    g2.drawString(label, (float)xx, (float)yy);

    }

  }

  // draw the tick labels and marks and gridlines

  this.refreshTicks(g2, drawArea, plotArea);

  double xx = plotArea.getX();

  g2.setFont(tickLabelFont);

  Iterator iterator = ticks.iterator();

  while (iterator.hasNext()) {

    Tick tick = (Tick)iterator.next();

    float yy = (float)this.translateValueToJava2D(tick.getNumericalValue(), plotArea);

    if (tickLabelsVisible) {

    g2.setPaint(this.tickLabelPaint);

    g2.drawString(tick.getText(), tick.getX(), tick.getY());

    }

    if (tickMarksVisible) {

    g2.setStroke(this.getTickMarkStroke());

    Line2D mark = new Line2D.Double(plotArea.getX()-2, yy,

            plotArea.getX()+2, yy);

    g2.draw(mark);

    }

    if (gridLinesVisible) {

    g2.setStroke(gridStroke);

    g2.setPaint(gridPaint);

    Line2D gridline = new Line2D.Double(xx, yy,

              plotArea.getMaxX(), yy);

    g2.draw(gridline);


================================================================================

Back to top

Take Away No. 5:

Among those methods sharing the same lead comments but have differences in the implementations ($32$ in total), None of them have differences in the coherence evaluation. This means that differences in the implementation were limited to syntactic constructs and names of the variables.

Back to top

Coherence of Methods with Different Comments but the Same Code


In [29]:
same_coherence = list()
coherence_changed = list()

for mkey in different_comment_same_code:
    mth_in_060 = jf060_methods[mkey]
    mth_in_071 = jf071_methods[mkey]
    
    if is_coherent(mth_in_060) == is_coherent(mth_in_071):
        same_coherence.append(mkey)
    else:
        coherence_changed.append(mkey)

In [30]:
print('Total Number of Methods having different comment but the same code', len(different_comment_same_code))
print('\t Same Coherence: ', len(same_coherence))
print('\t Different Coherence', len(coherence_changed))


Total Number of Methods having different comment but the same code 16
	 Same Coherence:  14
	 Different Coherence 2

In [31]:
# Try to slpot some insights
randomly_pick_a_method_from(coherence_changed, with_code=True, with_coherence=True)  # Method 1
randomly_pick_a_method_from(coherence_changed, with_code=True, with_coherence=True)  # Method 2


================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Returns the Paint used to color the grid lines (if visible).
   */

  public Paint getGridPaint() {
  return gridPaint;




Method in JFreeChart 0.7.1 Is Coherent:  False
/**

   * Returns the grid line color.

   * @return The grid line color.

   */

  public Paint getGridPaint() {

  return gridPaint;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Adds a horizontal line at location with given color.
   * @return void
   */

  public void addHorizontalLine(Number location, Paint color) {
    if (horizontalLines == null) {
      horizontalLines = new ArrayList();
      horizontalColors = new ArrayList();
    }
    horizontalColors.add(color);
    horizontalLines.add(location);




Method in JFreeChart 0.7.1 Is Coherent:  False
/**

   * Adds a horizontal line at the specified data value, using the specified color.

   * @param value The data value.

   * @param color The line color.

   */

  public void addHorizontalLine(Number location, Paint color) {

    if (horizontalLines == null) {

      horizontalLines = new ArrayList();

      horizontalColors = new ArrayList();

    }

    horizontalColors.add(color);

    horizontalLines.add(location);


================================================================================

Back to top

Take Away No. 6:

This is interesting.

There are just 2 cases in which differences in comments (and not in implementation) lead to different coherence evaluations.

As a matter of facts, the changes in the lead comments for methods gathered from JFreeChart 0.7.1 are not compliant with the corresponding code. For instance, in the latter case, the parameters listed in the Javadoc @param annotations are not all compliant with the corresponding method signature. This phenomenon may be likely due to refactoring changes (i.e. renaming of variables) not reflected in the comment.

Pick some examples from those methods who share the same coherence evaluations (instead)


In [32]:
# Try to spot some insights
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 1
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 2
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 3
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 4
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 5


================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Returns the format object used to format tick labels.
   */

  public SimpleDateFormat getTickLabelFormatter() {
  return tickLabelFormatter;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Returns the formatter for the tick labels.

   * @return The formatter for the tick labels.

   */

  public SimpleDateFormat getTickLabelFormatter() {

  return tickLabelFormatter;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  False
/**
   * Returns chart's backgroud area
   */

  protected Shape calculateBackgroundPlotArea(Rectangle2D plotArea) {
    return plotArea;




Method in JFreeChart 0.7.1 Is Coherent:  False
/**

   * Returns chart's background area.

   */

  protected Shape calculateBackgroundPlotArea(Rectangle2D plotArea) {

    return plotArea;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  False
/**
   * Full constructor - builds a new DateTitle with the specified attributes.
   * @param location the relative location of this title (use constants in AbstractTitle);
   * @param alignment the text alignment of this title (use constants in AbstractTitle);
   * @param dateStyle the Date style to use (SHORT, MEDIUM, LONG, or FULL constants from
   *          java.text.DateFormat);
   * @param locale the locale to use to format this date (if you are unsure what to use here, use
   *         Locale.getDefault() for your default locale);
   * @param font the font used to display the date;
   * @param paint the paint used to display the date;
   * @param insets the blank space around the outside of the title;
   */

  public DateTitle(int dateStyle, Locale locale, Font font, Paint paint, int position,
           int horizontalAlignment, int verticalAlignment, Insets insets) {

    super(DateFormat.getDateInstance(dateStyle, locale).format(new Date()),
        font, paint, position, horizontalAlignment, verticalAlignment, insets);




Method in JFreeChart 0.7.1 Is Coherent:  False
/**

   * Constructs a new DateTitle with the specified attributes.

   * @param location the relative location of this title (use constants in AbstractTitle).

   * @param alignment the text alignment of this title (use constants in AbstractTitle).

   * @param dateStyle the Date style to use (SHORT, MEDIUM, LONG, or FULL constants from

   *          java.text.DateFormat).

   * @param locale the locale to use to format this date (if you are unsure what to use here, use

   *         Locale.getDefault() for your default locale).

   * @param font the font used to display the date.

   * @param paint the paint used to display the date.

   * @param insets the blank space around the outside of the title.

   */

  public DateTitle(int dateStyle, Locale locale, Font font, Paint paint, int position,

           int horizontalAlignment, int verticalAlignment, Insets insets) {

    super(DateFormat.getDateInstance(dateStyle, locale).format(new Date()),

        font, paint, position, horizontalAlignment, verticalAlignment, insets);


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Sets the vertical alignment for the title, and notifies any registered listeners of the change.
   * The constants TOP, MIDDLE and BOTTOM (defined in this class) can be used to specify the
   * alignment.
   * @param alignment The new vertical alignment (TOP, MIDDLE or BOTTOM);
   */

  public void setVerticalAlignment(int alignment) {
    if (this.verticalAlignment!=alignment) {
      this.verticalAlignment = alignment;
      notifyListeners(new TitleChangeEvent(this));




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Sets the vertical alignment for the title, and notifies any registered listeners of the

   * change.

   * The constants TOP, MIDDLE and BOTTOM (defined in this class) can be used to specify the

   * alignment.

   * @param alignment The new vertical alignment (TOP, MIDDLE or BOTTOM);

   */

  public void setVerticalAlignment(int alignment) {

    if (this.verticalAlignment!=alignment) {

      this.verticalAlignment = alignment;

      notifyListeners(new TitleChangeEvent(this));


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Registers an object for notification of changes to the title.
   * @param listener The object that is being registered.
   */
 --------------
//notifyListeners(new TitleChangeEvent(this));
 --------------


  public void addChangeListener(TitleChangeListener listener) {
  listeners.add(listener);




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Registers an object for notification of changes to the title.

   * @param listener The object that is being registered.

   */

  public void addChangeListener(TitleChangeListener listener) {

  listeners.add(listener);


================================================================================

Back to top

Take Away No. 7:

This is also interesting.

In all other cases of common methods having differences in the lead comment but not in the implementation, it seems that the corresponding coherence is not affected.

As a matter of facts, all the changes and differences in the lead comments for methods gathered from JFreeChart 0.7.1 are limited to Javadoc syntax adjustments, typos corrections, and revisions of parameters and method's descriptions.

Back to top

Coherence of Methods with Different Comments and Code


In [33]:
same_coherence = list()
coherence_changed = list()

for mkey in different_comment_and_code:
    mth_in_060 = jf060_methods[mkey]
    mth_in_071 = jf071_methods[mkey]
    
    if is_coherent(mth_in_060) == is_coherent(mth_in_071):
        same_coherence.append(mkey)
    else:
        coherence_changed.append(mkey)

In [34]:
print('Total Number of Methods having different comment and code', len(different_comment_and_code))
print('\t Same Coherence: ', len(same_coherence))
print('\t Different Coherence', len(coherence_changed))


Total Number of Methods having different comment and code 10
	 Same Coherence:  9
	 Different Coherence 1

Pick some examples from those methods who share the same coherence evaluations


In [35]:
# Try to spot some insights
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 1
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 2
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 3
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 4
randomly_pick_a_method_from(same_coherence, with_code=True, with_coherence=True)  # Method 5


================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Full constructor - builds an abstract title with the specified position and alignment. This
   * class defines constants for the valid position and alignment values---an
   * IllegalArgumentException will be thrown if invalid values are passed to this constructor.
   * @param position The relative position of the title (TOP, BOTTOM, RIGHT and LEFT---or NORTH,
   *         SOUTH, EAST and WEST if you prefer);
   * @param horizontalAlignment The horizontal alignment of the title (LEFT, CENTER or RIGHT);
   * @param verticalAlignment The vertical alignment of the title (TOP, MIDDLE or BOTTOM);
   * @exception IllegalArgumentException If an invalid location or alignment value is passed;
   */

  protected AbstractTitle(int position, int horizontalAlignment, int verticalAlignment,
              Insets insets) {

    // check position
    if (!this.isValidPosition(position)) {
      throw new IllegalArgumentException("AbstractTitle: Invalid position.");
    }

    // check the horizontal and vertical alignment
    if ((horizontalAlignment!=LEFT) &&
      (horizontalAlignment!=CENTER) &&
      (horizontalAlignment!=RIGHT)) {
      throw new IllegalArgumentException("AbstractTitle: Invalid horizontal alignment.");
    }

    if ((verticalAlignment!=TOP) &&
      (verticalAlignment!=BOTTOM) &&
      (verticalAlignment!=MIDDLE)) {
      throw new IllegalArgumentException("AbstractTitle: Invalid vertical alignment.");
    }

    this.position = position;
    this.horizontalAlignment = horizontalAlignment;
    this.verticalAlignment = verticalAlignment;
    this.insets = insets;
    this.listeners = new java.util.ArrayList();
    this.notify = true;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Constructs a title.

   * <P>

   * This class defines constants for the valid position and alignment values---an

   * IllegalArgumentException will be thrown if invalid values are passed to this constructor.

   * @param position The relative position of the title (TOP, BOTTOM, RIGHT and LEFT---or NORTH,

   *         SOUTH, EAST and WEST if you prefer).

   * @param horizontalAlignment The horizontal alignment of the title (LEFT, CENTER or RIGHT).

   * @param verticalAlignment The vertical alignment of the title (TOP, MIDDLE or BOTTOM).

   * @exception IllegalArgumentException If an invalid location or alignment value is passed.

   */

  protected AbstractTitle(int position,

              int horizontalAlignment, int verticalAlignment, Insets insets) {

    // check arguments...

    if (!this.isValidPosition(position)) {

      throw new IllegalArgumentException("AbstractTitle(): Invalid position.");

    }

    if (!AbstractTitle.isValidHorizontalAlignment(horizontalAlignment)) {

      throw new IllegalArgumentException("AbstractTitle(): Invalid horizontal alignment.");

    }

    if (!AbstractTitle.isValidVerticalAlignment(verticalAlignment)) {

      throw new IllegalArgumentException("AbstractTitle(): Invalid vertical alignment.");

    }

    // initialise...

    this.position = position;

    this.horizontalAlignment = horizontalAlignment;

    this.verticalAlignment = verticalAlignment;

    this.insets = insets;

    this.listeners = new java.util.ArrayList();

    this.notify = true;


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Standard constructor - builds a VerticalCategoryAxis with mostly default attributes.
   * @param label The axis label;
   */

  public VerticalCategoryAxis(String label) {
  super(label);
  this.verticalLabel = true;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Constructs a VerticalCategoryAxis, using default attributes where necessary.

   * @param label The axis label.

   */

  public VerticalCategoryAxis(String label) {

    this(label,

       Axis.DEFAULT_AXIS_LABEL_FONT,

       Axis.DEFAULT_AXIS_LABEL_PAINT,

       Axis.DEFAULT_TICK_LABEL_INSETS,

       true, // vertical label

       true, // category labels visible

       Axis.DEFAULT_TICK_LABEL_FONT,

       Axis.DEFAULT_TICK_LABEL_PAINT,

       Axis.DEFAULT_TICK_LABEL_INSETS,

       false, // tick marks visible

       Axis.DEFAULT_TICK_STROKE);


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Constructs a value axis.
   * @param label The axis label.
   */

  public ValueAxis(String label) {
  super(label);
  this.autoRange = true;
  this.autoTickUnit = true;
  this.showGridLines = true;
  this.gridStroke = ValueAxis.DEFAULT_GRID_LINE_STROKE;
    this.gridPaint = Color.gray;




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Constructs a value axis, using default values where necessary.

   * @param label The axis label.

   */

  public ValueAxis(String label) {

  this(label,

       Axis.DEFAULT_AXIS_LABEL_FONT,

       Axis.DEFAULT_AXIS_LABEL_PAINT,

       Axis.DEFAULT_AXIS_LABEL_INSETS,

       true, // tick labels visible

       Axis.DEFAULT_TICK_LABEL_FONT,

       Axis.DEFAULT_TICK_LABEL_PAINT,

       Axis.DEFAULT_TICK_LABEL_INSETS,

       true, // tick marks visible

       Axis.DEFAULT_TICK_STROKE,

       true, // auto range

       true, // auto tick unit

       true, // show grid lines

       ValueAxis.DEFAULT_GRID_LINE_STROKE,

       ValueAxis.DEFAULT_GRID_LINE_PAINT,

       0.0,  // crosshair

       ValueAxis.DEFAULT_CROSSHAIR_STROKE,

       ValueAxis.DEFAULT_CROSSHAIR_PAINT);


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Standard constrcutor - builds an abstract title with the specified position and alignment,
   * with a default inset of 2 pixels around the title.  This class defines constants for the valid
   * position and alignment values---an IllegalArgumentException will be thrown if invalid values
   * are passed to this constructor.
   * @param position The relative position of the title (TOP, BOTTOM, RIGHT and LEFT---or NORTH,
   *         SOUTH, EAST and WEST if you prefer);
   * @param horizontalAlignment The horizontal alignment of the title (LEFT, CENTER or RIGHT);
   * @param verticalAlignment The vertical alignment of the title (TOP, MIDDLE or BOTTOM);
   * @exception IllegalArgumentException If an invalid location or alignment value is passed;
   */

  protected AbstractTitle(int position, int horizontalAlignment, int verticalAlignment) {
    this(position, horizontalAlignment, verticalAlignment, new Insets(2, 2, 2, 2));




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Constructs a title.

   * @param position The relative position of the title (TOP, BOTTOM, RIGHT and LEFT---or NORTH,

   *         SOUTH, EAST and WEST if you prefer);

   * @param horizontalAlignment The horizontal alignment of the title (LEFT, CENTER or RIGHT);

   * @param verticalAlignment The vertical alignment of the title (TOP, MIDDLE or BOTTOM);

   * @exception IllegalArgumentException If an invalid location or alignment value is passed;

   */

  protected AbstractTitle(int position, int horizontalAlignment, int verticalAlignment) {

    this(position,

       horizontalAlignment, verticalAlignment,

       AbstractTitle.DEFAULT_INSETS);


================================================================================

================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  True
/**
   * Sets the gap between the last bar in one category and the first bar in the
   * next category, and notifies registered listeners that the plot has been modified.
   * @param gap The new gap value.
   */

  public void setCategoryGapsPercent(double percent) {
  if (this.categoryGapsPercent!=percent) {
      this.categoryGapsPercent=Math.min(percent, MAX_CATEGORY_GAPS_PERCENT);
    notifyListeners(new PlotChangeEvent(this));




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Sets the gap between the last bar in one category and the first bar in the

   * next category, and notifies registered listeners that the plot has been modified.

   * @param percent The new gap value, expressed as a percentage of the width of the plot area

   *        (0.05 = 5 percent).

   */

  public void setCategoryGapsPercent(double percent) {

    // check argument...

    if ((percent<0.0) || (percent>MAX_CATEGORY_GAPS_PERCENT)) {

      throw new IllegalArgumentException("BarPlot.setCategoryGapsPercent(double): argument "

                        +"outside valid range.");

    }

    // make the change...

  if (this.categoryGapsPercent!=percent) {

      this.categoryGapsPercent=percent;

    notifyListeners(new PlotChangeEvent(this));


================================================================================

Back to top

Take Away No. 8:

This is interesting as well!!.

Among the $10$ methods in common between the two versions that have differences in code and comments, $9$ of them have the same evaluation of coherence.

This phenomenon reflects the fact that in these $9$ cases, code and comments have been updated accordingly!

However, if we look at the totality of common methods, this number is ridiculous!

In more details, it is $9$ methods out of $58$, $\approx 16\%$, where $58$ corresponds to $283$ (methods in common) minus those with no real difference in code and comments ($225$ - the majority of them)!!

Pick the ONLY example where differences in code and comments have reflected changes in the coherence evaluation


In [36]:
# Try to spot some insights
randomly_pick_a_method_from(coherence_changed, with_code=True, with_coherence=True)  # Method 1


================================================================================
Method in JFreeChart 0.6.0 Is Coherent:  False
/**
   * Default constructor.
   */

  public VerticalNumberAxis3D() {
  super(null);




Method in JFreeChart 0.7.1 Is Coherent:  True
/**

   * Constructs a VerticalNumberAxis3D, with no label and default attributes.

   */

  public VerticalNumberAxis3D() {

  this(null);


================================================================================

Back to top

Take Away No. 9:

This is interesting (and correct)!!.

In the only case (out of 10) where there is difference in the coherence evaluation between the two methods in common, the corresponding lead comments and implementations have been updated accordingly!

In fact, while there was no coherence for the method extracted from JFreeChart 0.6.0, there is for the one from JfreeChart 0.7.1.

Back to top

Analysis of Methods NOT in Common


In [37]:
methods_in_060 = set(jf060_methods.keys())
methods_in_071 = set(jf071_methods.keys())

# Set of Methods in 0.6.0 and not in 0.7.1
methods_in_060_not_in_071 = methods_in_060.difference(methods_in_071)
print('Total No. of Methods in JfreeChart 0.6.0 and NOT in 0.7.1: ', len(methods_in_060_not_in_071))

print('-'*80)

# Set of Methods in 0.7.1 and not in 0.6.0
methods_in_071_not_in_060 = methods_in_071.difference(methods_in_060)
print('Total No. of Methods in JfreeChart 0.7.1 and NOT in 0.6.0: ', len(methods_in_071_not_in_060))


Total No. of Methods in JfreeChart 0.6.0 and NOT in 0.7.1:  178
--------------------------------------------------------------------------------
Total No. of Methods in JfreeChart 0.7.1 and NOT in 0.6.0:  305

Percentage of Coherente / Not Coherent Methods

Analyse how many of the methods in the difference between the two versions are Coherent or Not Coherent

Back to top

JFreeChart 0.6.0


In [38]:
coherent = list()
not_coherent = list()

for mkey in methods_in_060_not_in_071:
    method = jf060_methods[mkey]
    if is_coherent(method):
        coherent.append(mkey)
    else:
        not_coherent.append(mkey)
        
print('Total Number of Methods in JFreeChart 0.6.0 but NOT in 0.7.1:', len(methods_in_060_not_in_071))
print('\t Coherent: ', len(coherent))
print('\t Not Coherent', len(not_coherent))


Total Number of Methods in JFreeChart 0.6.0 but NOT in 0.7.1: 178
	 Coherent:  146
	 Not Coherent 32

Back to top

JFreeChart 0.7.1


In [39]:
coherent = list()
not_coherent = list()

for mkey in methods_in_071_not_in_060:
    method = jf071_methods[mkey]
    if is_coherent(method):
        coherent.append(mkey)
    else:
        not_coherent.append(mkey)
        
print('Total Number of Methods in JFreeChart 0.7.1 but NOT in 0.6.0:', len(methods_in_071_not_in_060))
print('\t Coherent: ', len(coherent))
print('\t Not Coherent', len(not_coherent))


Total Number of Methods in JFreeChart 0.7.1 but NOT in 0.6.0: 305
	 Coherent:  256
	 Not Coherent 49

Back to top

(Likely) Modified Methods from JFreeChart 0.6.0 to 0.7.1

In this section, the main purpose of the analysis is to try to check some possible matches between methods not in JFreeChart 0.6.0 but present in JFreeChart 0.7.1.

The main idea is that we would like to find (or guess) all those methods whose signature has been changed/updated thus not appearing in the set of Common Methods.


In [40]:
# Analyse the differences: Try to guess if there is some method that has been CHANGED between the two versions
from collections import defaultdict
associations_map = defaultdict(list)

def match(method_key, target_class, target_file, target_signature_stub):
    """We try to infer a possible matching between two methods if they share:
    - the same class name
    - the same source file name
    - their signature starts with the same _stub_
        In particular, the `target_signature_stub` corresponds to the 
        first part of the signature till the first open paranthesis, i.e. "("
    """
    mth = jf060_methods[method_key]
    return (method_key not in jf071_methods and 
            mth.code_class.src_filename == target_file 
            and mth.code_class.class_name == target_class and 
            signature(mth.code_fragment).startswith(target_signature_stub))
    

# Iterate over all methods in JFreeChart 0.7.1 and NOT in 0.6.0
# in order to guess some possible signature matchings
for mkey in methods_in_071_not_in_060:
    method = jf071_methods[mkey]
    signature_071 = signature(method.code_fragment)
    
    # get all the methods whose signature starts similarly to the target method
    signature_stub = signature_071[:signature_071.find('(')]
    class_name = method.code_class.class_name
    src_file = method.code_class.src_filename
    associations = list(filter(lambda k: match(k, class_name, src_file, signature_stub), 
                               jf060_methods.keys()))
    associations_map[mkey] = associations

In [41]:
# Filter out all that had no matching in the first place
possible_mappings = {k:v for k, v in associations_map.items() if len(v)}

In [42]:
print('We inferred a total of {} matchings for {} methods NOT in common!'.format(len(possible_mappings), 
                                                                                 len(methods_in_071_not_in_060)))


We inferred a total of 28 matchings for 305 methods NOT in common!

In [43]:
# Print Matchings Guessed
for mkey, associations in possible_mappings.items():
    print('Target Signature: ', signature(jf071_methods[mkey].code_fragment))
    print('Possible Associations in Total: ', len(associations))
    for i, assoc in enumerate(associations):
        print('\t {}): '.format(i+1), assoc, end="\n\n")
    print('-'*80)


Target Signature:  public HorizontalBarPlot(Axis horizontalAxis, Axis verticalAxis)
Possible Associations in Total:  2
	 1):  HorizontalBarPlot.javaHorizontalBarPlotpublic HorizontalBarPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  HorizontalBarPlot.javaHorizontalBarPlotpublic HorizontalBarPlot(Axis horizontalAxis, Axis verticalAxis, Insets insets, double introGapPercent, double trailGapPercent, double categoryGapPercent, double seriesGapPercent) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  private void drawVerticalLine(Graphics2D g2, Rectangle2D dataArea, double value, Stroke stroke, Paint paint)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotprivate void drawVerticalLines(Graphics2D g2, Rectangle2D plotArea)

--------------------------------------------------------------------------------
Target Signature:  public void draw(Graphics2D g2, Rectangle2D plotArea, DrawInfo info)
Possible Associations in Total:  1
	 1):  VerticalBarPlot.javaVerticalBarPlotpublic void draw(Graphics2D g2, Rectangle2D drawArea)

--------------------------------------------------------------------------------
Target Signature:  public HorizontalBarPlot(Axis horizontalAxis, Axis verticalAxis, Insets insets, double introGapPercent, double trailGapPercent, double categoryGapPercent, double itemGapPercent, CategoryToolTipGenerator toolTipGenerator)
Possible Associations in Total:  2
	 1):  HorizontalBarPlot.javaHorizontalBarPlotpublic HorizontalBarPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  HorizontalBarPlot.javaHorizontalBarPlotpublic HorizontalBarPlot(Axis horizontalAxis, Axis verticalAxis, Insets insets, double introGapPercent, double trailGapPercent, double categoryGapPercent, double seriesGapPercent) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public VerticalNumberAxis3D(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean verticalLabel, boolean showTickLabels, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean showTickMarks, Stroke tickMarkStroke, boolean autoRange, boolean autoRangeIncludesZero, Number autoRangeMinimum, double minimumAxisValue, double maximumAxisValue, boolean inverted, boolean autoTickUnit, NumberTickUnit tickUnit, boolean showGridLines, Stroke gridStroke, Paint gridPaint, double crosshairValue, Stroke crosshairStroke, Paint crosshairPaint, double effect3d)
Possible Associations in Total:  2
	 1):  VerticalNumberAxis3D.javaVerticalNumberAxis3Dpublic VerticalNumberAxis3D(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean verticalLabel, boolean showTickLabels, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean showTickMarks, Stroke tickMarkStroke, boolean autoRange, boolean autoRangeIncludesZero, Number autoRangeMinimum, Number minimumAxisValue, Number maximumAxisValue, boolean autoTickUnit, NumberTickUnit tickUnit, /*Number tickValue, DecimalFormat formatter,*/ boolean showGridLines, Stroke gridStroke, Paint gridPaint, double effect3d)

	 2):  VerticalNumberAxis3D.javaVerticalNumberAxis3Dpublic VerticalNumberAxis3D(String label, Font labelFont, Number minimumAxisValue, Number maximumAxisValue)

--------------------------------------------------------------------------------
Target Signature:  public VerticalBarPlot(CategoryAxis horizontalAxis, ValueAxis verticalAxis)
Possible Associations in Total:  2
	 1):  VerticalBarPlot.javaVerticalBarPlotpublic VerticalBarPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  VerticalBarPlot.javaVerticalBarPlotpublic VerticalBarPlot(Axis horizontal, Axis vertical, Insets insets, double introGapPercent, double trailGapPercent, double categoryGapPercent, double seriesGapPercent) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public VerticalBarPlot3D(CategoryAxis horizontalAxis, ValueAxis verticalAxis)
Possible Associations in Total:  2
	 1):  VerticalBarPlot3D.javaVerticalBarPlot3Dpublic VerticalBarPlot3D(Axis horizontal, Axis vertical, Insets insets, double introGap, double trailGap, double categoryGap, double seriesGap) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  VerticalBarPlot3D.javaVerticalBarPlot3Dpublic VerticalBarPlot3D(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public void addHorizontalLine(Number value)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotpublic void addHorizontalLine(Number location)

--------------------------------------------------------------------------------
Target Signature:  protected void drawBars(Graphics2D g2, Shape backgroundPlotArea, Rectangle2D plotArea, DrawInfo info)
Possible Associations in Total:  1
	 1):  VerticalBarPlot3D.javaVerticalBarPlot3Dprotected void drawBars(Graphics2D g2, Shape backgroundPlotArea, Rectangle2D plotArea)

--------------------------------------------------------------------------------
Target Signature:  public VerticalXYBarPlot(Axis horizontalAxis, Axis verticalAxis, Insets insets, Paint background, Stroke outlineStroke, Paint outlinePaint)
Possible Associations in Total:  2
	 1):  VerticalXYBarPlot.javaVerticalXYBarPlotpublic VerticalXYBarPlot(Axis horizontalAxis, Axis verticalAxis, Insets insets, Paint background, Stroke outlineStroke, Paint outlinePaint) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  VerticalXYBarPlot.javaVerticalXYBarPlotpublic VerticalXYBarPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public VerticalCategoryAxis(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean verticalLabel, boolean categoryLabelsVisible, Font categoryLabelFont, Paint categoryLabelPaint, Insets categoryLabelInsets, boolean tickMarksVisible, Stroke tickMarkStroke)
Possible Associations in Total:  1
	 1):  VerticalCategoryAxis.javaVerticalCategoryAxispublic VerticalCategoryAxis(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean verticalLabel, boolean showTickLabels, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean showTickMarks, Stroke tickMarkStroke)

--------------------------------------------------------------------------------
Target Signature:  private void drawVerticalLines(Graphics2D g2, Rectangle2D dataArea)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotprivate void drawVerticalLines(Graphics2D g2, Rectangle2D plotArea)

--------------------------------------------------------------------------------
Target Signature:  public VerticalNumberAxis(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean labelDrawnVertical, boolean tickLabelsVisible, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean tickMarksVisible, Stroke tickMarkStroke, boolean autoRange, boolean autoRangeIncludesZero, Number autoRangeMinimum, double minimumAxisValue, double maximumAxisValue, boolean inverted, boolean autoTickUnitSelection, NumberTickUnit tickUnit, boolean gridLinesVisible, Stroke gridStroke, Paint gridPaint, double crosshairValue, Stroke crosshairStroke, Paint crosshairPaint)
Possible Associations in Total:  2
	 1):  VerticalNumberAxis.javaVerticalNumberAxispublic VerticalNumberAxis(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean labelDrawnVertical, boolean tickLabelsVisible, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean tickMarksVisible, Stroke tickMarkStroke, boolean autoRange, boolean autoRangeIncludesZero, Number autoRangeMinimum, Number minimumAxisValue, Number maximumAxisValue, boolean autoTickUnitSelection, NumberTickUnit tickUnit, boolean gridLinesVisible, Stroke gridStroke, Paint gridPaint)

	 2):  VerticalNumberAxis.javaVerticalNumberAxispublic VerticalNumberAxis(String label, Font labelFont, Number minimumAxisValue, Number maximumAxisValue)

--------------------------------------------------------------------------------
Target Signature:  public void draw(Graphics2D g2, Rectangle2D plotArea, DrawInfo info)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotpublic void draw(Graphics2D g2, Rectangle2D drawArea)

--------------------------------------------------------------------------------
Target Signature:  public VerticalBarPlot(CategoryAxis horizontalAxis, ValueAxis verticalAxis, Insets insets, double introGapPercent, double trailGapPercent, double categoryGapPercent, double itemGapPercent, CategoryToolTipGenerator toolTipGenerator)
Possible Associations in Total:  2
	 1):  VerticalBarPlot.javaVerticalBarPlotpublic VerticalBarPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  VerticalBarPlot.javaVerticalBarPlotpublic VerticalBarPlot(Axis horizontal, Axis vertical, Insets insets, double introGapPercent, double trailGapPercent, double categoryGapPercent, double seriesGapPercent) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public VerticalNumberAxis(String label, Font labelFont, double minimumAxisValue, double maximumAxisValue)
Possible Associations in Total:  2
	 1):  VerticalNumberAxis.javaVerticalNumberAxispublic VerticalNumberAxis(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean labelDrawnVertical, boolean tickLabelsVisible, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean tickMarksVisible, Stroke tickMarkStroke, boolean autoRange, boolean autoRangeIncludesZero, Number autoRangeMinimum, Number minimumAxisValue, Number maximumAxisValue, boolean autoTickUnitSelection, NumberTickUnit tickUnit, boolean gridLinesVisible, Stroke gridStroke, Paint gridPaint)

	 2):  VerticalNumberAxis.javaVerticalNumberAxispublic VerticalNumberAxis(String label, Font labelFont, Number minimumAxisValue, Number maximumAxisValue)

--------------------------------------------------------------------------------
Target Signature:  public VerticalNumberAxis3D(String label, Font labelFont, double minimumAxisValue, double maximumAxisValue)
Possible Associations in Total:  2
	 1):  VerticalNumberAxis3D.javaVerticalNumberAxis3Dpublic VerticalNumberAxis3D(String label, Font labelFont, Paint labelPaint, Insets labelInsets, boolean verticalLabel, boolean showTickLabels, Font tickLabelFont, Paint tickLabelPaint, Insets tickLabelInsets, boolean showTickMarks, Stroke tickMarkStroke, boolean autoRange, boolean autoRangeIncludesZero, Number autoRangeMinimum, Number minimumAxisValue, Number maximumAxisValue, boolean autoTickUnit, NumberTickUnit tickUnit, /*Number tickValue, DecimalFormat formatter,*/ boolean showGridLines, Stroke gridStroke, Paint gridPaint, double effect3d)

	 2):  VerticalNumberAxis3D.javaVerticalNumberAxis3Dpublic VerticalNumberAxis3D(String label, Font labelFont, Number minimumAxisValue, Number maximumAxisValue)

--------------------------------------------------------------------------------
Target Signature:  public void setHorizontalAxis(Axis axis)
Possible Associations in Total:  1
	 1):  BarPlot.javaBarPlotpublic void setHorizontalAxis(Axis axis) throws AxisNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public void draw(Graphics2D g2, Rectangle2D drawArea, DrawInfo info)
Possible Associations in Total:  1
	 1):  VerticalXYBarPlot.javaVerticalXYBarPlotpublic void draw(Graphics2D g2, Rectangle2D drawArea)

--------------------------------------------------------------------------------
Target Signature:  public void setVerticalAxis(Axis axis)
Possible Associations in Total:  1
	 1):  BarPlot.javaBarPlotpublic void setVerticalAxis(Axis axis) throws AxisNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  private void drawHorizontalLines(Graphics2D g2, Rectangle2D dataArea)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotprivate void drawHorizontalLines(Graphics2D g2, Rectangle2D plotArea)

--------------------------------------------------------------------------------
Target Signature:  private void drawHorizontalLine(Graphics2D g2, Rectangle2D dataArea, double value, Stroke stroke, Paint paint)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotprivate void drawHorizontalLines(Graphics2D g2, Rectangle2D plotArea)

--------------------------------------------------------------------------------
Target Signature:  protected void drawBars(Graphics2D g2, Shape backgroundPlotArea, Rectangle2D dataArea, DrawInfo info)
Possible Associations in Total:  1
	 1):  VerticalBarPlot.javaVerticalBarPlotprotected void drawBars(Graphics2D g2, Shape backgroundPlotArea, Rectangle2D plotArea)

--------------------------------------------------------------------------------
Target Signature:  public void draw(Graphics2D g2, Rectangle2D plotArea, DrawInfo info)
Possible Associations in Total:  1
	 1):  HorizontalBarPlot.javaHorizontalBarPlotpublic void draw(Graphics2D g2, Rectangle2D drawArea)

--------------------------------------------------------------------------------
Target Signature:  public VerticalBarPlot3D(CategoryAxis horizontalAxis, ValueAxis verticalAxis, Insets insets, double introGap, double trailGap, double categoryGap, double seriesGap, CategoryToolTipGenerator toolTipGenerator)
Possible Associations in Total:  2
	 1):  VerticalBarPlot3D.javaVerticalBarPlot3Dpublic VerticalBarPlot3D(Axis horizontal, Axis vertical, Insets insets, double introGap, double trailGap, double categoryGap, double seriesGap) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  VerticalBarPlot3D.javaVerticalBarPlot3Dpublic VerticalBarPlot3D(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public VerticalXYBarPlot(Axis horizontalAxis, Axis verticalAxis)
Possible Associations in Total:  2
	 1):  VerticalXYBarPlot.javaVerticalXYBarPlotpublic VerticalXYBarPlot(Axis horizontalAxis, Axis verticalAxis, Insets insets, Paint background, Stroke outlineStroke, Paint outlinePaint) throws AxisNotCompatibleException, PlotNotCompatibleException

	 2):  VerticalXYBarPlot.javaVerticalXYBarPlotpublic VerticalXYBarPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public XYPlot(ValueAxis horizontalAxis, ValueAxis verticalAxis, Insets insets, Paint background, Stroke outlineStroke, Paint outlinePaint)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotpublic XYPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------
Target Signature:  public XYPlot(ValueAxis horizontalAxis, ValueAxis verticalAxis)
Possible Associations in Total:  1
	 1):  XYPlot.javaXYPlotpublic XYPlot(Axis horizontalAxis, Axis verticalAxis) throws AxisNotCompatibleException, PlotNotCompatibleException

--------------------------------------------------------------------------------

Conclusion

Most of the guessed matchings are reasonable - most of them have just one possible match. Of course, we should manually dive more deeply into the code to check whether or not these methods actually corresponds to the same methods that has been changed between the two versions.

However, we may conclude that most of the methods present in the JFreeChart 0.7.1 version (but not in version 0.6.0) have been added in the new version!

Summary

  • JFreeChart 0.6.0 and 0.7.1 have $283$ methods in common

    • For each systems, methods are uniquely identified by a the tuple: (Name of the File, Name of the Class, Method Signature).
    • Methods with the same tuple in both systems are thus considered the same method.
  • Methods in Common have been further analysed (and grouped) in terms of similarities (differences) in their lead comment and implementation. In more details:

    • As for the Comment:

      • $257$ methods have the same lead comment (apart from some differences in layout and formattings)
      • $26$ methods have different lead comments.
    • As for the Implementation:

      • $225$ methods sharing the same comment have (also) the same comment;
      • $32$ methods sharing the same comment have different implementation.

        Similarly:

      • $16$ methods share the same code but have different comments;
      • $10$ methods have differences in code and comment
  • As for the Coherence:

    • For methods with the same code and same comment
      • There is no difference in coherence (crosscheck) as expected
    • For methods with the same comment but different code, we have

      • We experienced no difference as well. In fact, changes in code are limited to small refactoring operations (e.g. variable renaming or try catch blocks addition) which did not affect the semantic of the whole implementation.
    • For methods with different comment but the same code, we have:

      • $14$ methods having the same coherence evaluation
      • $2$ methods have different coherence In the first case, changes in comments reflect small adjustments in the Javadoc syntax as well as revisions in the method's description. On ther hand, the two cases in which there were differences in the coherence refer to methods in which the lead comments are not aligned with the corresponding implementation (only partial changes to the comments).
    • For methods with different code and comment, we have:

      • $9$ methods have the same coherence evaluation. This means that in these cases both comments and implementations have been updated accordingly in the two versions.
      • $1$ method has different coherence evaluation. In this particular example, changes in comment and implementations improved the coherence of this method. In fact, this method was non-coherent in JFreeChart 0.6.0, while it is finally coherent in version 0.7.1.